/**
 * 设置 swagger json
*/
/**
 * json 处理
*/
import { ModelMeta, PathMeta, ParamMeta, OperationMeta } from './Meta'
import Swagger from './index'
import { DataFormat } from '../router'

// 将 model 和 list 处理成 schema 对象
function getJsomSchema( a: ParamMeta[] | ParamMeta, b?: ParamMeta[] | ParamMeta) {
  let list = []
  let model = null
  if (Array.isArray(a)) {
    list = a
    model = b
  } else if (a) {
    model = a
  }

  const result: any = {}

  result.type = 'object'


  // 单个 Model
  if (model) {
    Object.assign(result, model.type)
  }

  // 逐个设置参数
  if (list.length) {
    Object.assign(result, {
      properties: (function() {
        const properties = {}

        list.reverse().forEach(paramMeta => {
          properties[paramMeta.name] = paramMeta
        })

        return properties
      })()
    })
  }
  

  return result
}

// 将 model 和 list 合并成一个列表
function getMegeToList(operationMeta: OperationMeta, a: ParamMeta[] | ParamMeta, b?: ParamMeta[] | ParamMeta): any[] | any {
  let list = []
  let model = null
  if (Array.isArray(a)) {
    list = a
    model = b
  } else if (a) {
    model = a
  }


  const SwaggerJSON = Swagger.getSwaggerJSON()

  if (model) {
    let modelName = ''

    // model 数组 或者对象 不合并
    if (model.type && (model.type.type === 'array' || model.type.type === 'object')) {
      if (model.type.type === 'array') {
        return model
      } else if (model.type.type === 'object') {
        return list
      }
    }
    
    try {
      modelName = model.type.$ref.split('/')[2]
    } catch (error) {
      throw new Error('model.type.$ref 不正确')
    }

    const properties = SwaggerJSON.definitions[modelName].properties

    

    Object.keys(properties).reverse().forEach(key => {
      const item = properties[key]
      list.push({
        name: key,
        description: item.description,
        type: item.type,
        default: item.default,
        // 实体类没有 in 属性，直接根据请求方式来设置
        // in: [DataFormat.FORMDATA, DataFormat.FORMDATA_CUSTOM, DataFormat.JSON].includes(operationMeta.dataFormat) ? 'formData' : 'query'
        in: operationMeta.httpMethod === 'get' ? 'query' : 'formData'
      })
    })
    
  }
  
  return list.map(item => Object.assign({}, item,
    typeof item.type === 'object' ? item.type : {},
  {
    in: item.in,
    // param 参数必填
    required: item.in === 'path' ? true : item.required
  }))
}

export function setSwaggerJSONByModelMeta(modelMeta: ModelMeta) {
  const SwaggerJSON = Swagger.getSwaggerJSON()

  modelMeta.isCreateTag && SwaggerJSON.tags.push({
    name: modelMeta.name,
    description: modelMeta.description
  })

  // 添加实体类
  if (!modelMeta.isCreateModel) return
  
  if (SwaggerJSON.definitions[modelMeta.name]) {
    throw new Error(`${modelMeta.name} Model 已存在`)
  }
  SwaggerJSON.definitions[modelMeta.name] = {
    description: modelMeta.description,
    type: 'object',
    // 设置实体类属性
    properties: (function() {
      const result = {}
      modelMeta.modelPropertyMetaList.forEach(modelPropertyMeta => {
        if (result[modelPropertyMeta.property]) {
          throw new Error(`${modelMeta.name} Model ${modelPropertyMeta.property} 已存在`)
        } else {
          result[modelPropertyMeta.property] = Object.assign(modelPropertyMeta.type, {
            description: modelPropertyMeta.description,
            default: modelPropertyMeta.default
          })
        }
      })
      return result
    })()
  }
}

export function setSwaggerJSONByPathMeta(pathMeta: PathMeta) {
  const SwaggerJSON = Swagger.getSwaggerJSON()

  // 设置 SwaggerJson 路径
  pathMeta.operationMetaList.forEach(operationMeta => {
    const path = {
      [operationMeta.httpMethod]: {
        tags: pathMeta.tags,
        summary: operationMeta.summary,
        description: operationMeta.description,
        consumes: [ operationMeta.dataFormat.trim() ],
        produces: [ operationMeta.dataFormat.trim() ],
        parameters: (function() {
          if (operationMeta.dataFormat === DataFormat.JSON && operationMeta.httpMethod === 'post') {
            return [{
              name: 'body',
              in: 'body',
              description: operationMeta.parameterModel ? operationMeta.parameterModel.description : '',
              required: true,
              schema: getJsomSchema(getMegeToList(operationMeta, operationMeta.parameterList, operationMeta.parameterModel), null)
            }]
          } else {
            return getMegeToList(operationMeta, operationMeta.parameterList, operationMeta.parameterModel)
          }
        })(),
        responses: { 200: {
          description: '',
          schema: (function() {
            if (operationMeta.responseModel || operationMeta.responseList.length) {
              return getJsomSchema(getMegeToList(operationMeta, operationMeta.responseList, operationMeta.responseModel), null)
            } else if (Swagger.DefaultResponseModel) {
              return { $ref: `#/definitions/${Swagger.DefaultResponseModel}` }
            } else {
              return { type: 'string' }
            }
          })()
        } }
      }
    }

    let url = pathMeta.path + operationMeta.path

    // 处理地址中的 param 参数
    if (url.includes(':')) {
      const keywords = url.split('/').filter(item => item.includes(':'))

      keywords.forEach(key => {
        url = url.replace(key, `{${key.replace(':', '')}}`)
      })
    }

    SwaggerJSON.paths[url] = path
  })
}

